package aufgabe6;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;

public class ExtIntClassifier {
	
	// values as log-values
	private Map<Character,Double> f_ext = new HashMap<Character, Double>();
	
	// values as log-values
	private Map<Character,Double> f_int = new HashMap<Character, Double>();
	
	private double p_ext, p_int;	
	
	public ExtIntClassifier(double p_ext, double p_int) {
		this.p_ext = p_ext;
		this.p_int = p_int;
	}

	/**
	 * Function P(ext|x).
	 * Result is in log with base e.
	 * 
	 * @param x 
	 * @return
	 */
	public double p(String x) {
		double p_x_ext = 0.0, p_x_int = 0.0;		
		
		for(char i: x.toCharArray()) {			
			p_x_ext += (f_ext.containsKey(i)) ? f_ext.get(i) : 0.0;
			p_x_int += (f_int.containsKey(i)) ? f_int.get(i) : 0.0;
		}
		
		// p = a / a + b  ---  a and b are log values
		
		double a = p_x_ext+Math.log(p_ext);
		double b = p_x_int+Math.log(p_int);
		
		// apply sum and quotient rule		
		return a - (a + Math.log(1 + Math.exp(b - a)));
	}
	
	public void readProbabilities(String extFilename, String intFilename) {
		readProbabilitiesFromFile(extFilename, 0);
		readProbabilitiesFromFile(intFilename, 1);
	}
	
	public void readProbabilitiesFromFile(String filename, int type) {
		try {
			BufferedReader br = new BufferedReader(new FileReader(new File(filename)));
	        String line;	        
	        
	        while((line = br.readLine()) != null) {
	        	if (line.equals("")) {	        		
	        		continue;
	        	}
	        	
	        	if (type == 0) {
	        		f_ext.put(line.charAt(0), Double.parseDouble(line.substring(2)));
	        	}
	        	else if (type == 1) {
	        		f_int.put(line.charAt(0), Double.parseDouble(line.substring(2)));
	        	}
	        }			
			
	        br.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void processFile(String inFilename) {
		try {	
			BufferedReader br = new BufferedReader(new FileReader(new File(inFilename)));
	        String line;
	        double threshold = Math.log(0.5);
	        String name = "";	        
	        
	        while((line = br.readLine()) != null) {
	        	if (line.startsWith(">")) {
	        		name = line.substring(line.indexOf("|")+1);
	        		name = name.substring(0, name.indexOf("|"));
	        		continue;
	        	}

	        	String type = (p(line) > threshold) ? "ext" : "int";
	        	
				System.out.println(name + "\t" + type);
	        }			
			
	        br.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length != 5) {
			System.out.println("Usage: BayesClassifier p_ext p_int \"ext_training_file\" \"int_training_file\" \"to_classify_file\"");
			System.exit(1);
		}
		
		ExtIntClassifier eic = new ExtIntClassifier(Double.parseDouble(args[0]), Double.parseDouble(args[1]));
		
		eic.readProbabilities(args[2], args[3]);
		
		eic.processFile(args[4]);
	}

}
